[gcc] Replace rsp/rbp lea base with esp/ebp This is yet another fix for POINTERS_EXTEND_UNSIGNED > 0 problem of keeping high part of rsp/rbp. In addition, minor fix for previous change - do not assert if writing rsp/rbp into memory (probably spill)? Test (-O1) must return 0 but returns high part of rsp without the fix: struct StringRef { const char *Data; unsigned Length; }; // Prevent inlining with 'weak' attribute int print_size(struct StringRef Data) __attribute__((weak)); int print_size(struct StringRef Data) { return Data.Length; } int main() { char str[6]; // NEEDED! struct StringRef s; s.Data = str + 3; // NEEDED! s.Length = 0; return print_size(s); } BUG=http://code.google.com/p/nativeclient/issues/detail?id=1304 TEST=see above Review URL: http://codereview.chromium.org/6271009 diff --git a/gcc/gcc/config/i386/i386-protos.h b/gcc/gcc/config/i386/i386-protos.h index 3cd5368..a79d1af 100644 --- a/gcc/gcc/config/i386/i386-protos.h +++ b/gcc/gcc/config/i386/i386-protos.h
@@ -263,6 +263,7 @@ extern int lea_match_address_operand (rtx, enum machine_mode); extern int ix86_decompose_address (rtx, struct ix86_address *); +extern int ix86_lea_decompose_address (rtx, struct ix86_address *); extern int memory_address_length (rtx addr); extern void x86_output_aligned_bss (FILE *, tree, const char *, unsigned HOST_WIDE_INT, int);
diff --git a/gcc/gcc/config/i386/i386.c b/gcc/gcc/config/i386/i386.c index 82802ef..7687ca0 100644 --- a/gcc/gcc/config/i386/i386.c +++ b/gcc/gcc/config/i386/i386.c
@@ -1818,7 +1818,6 @@ static bool ix86_valid_target_attribute_inner_p (tree, char *[]); static bool ix86_can_inline_p (tree, tree); static void ix86_set_current_function (tree); -static int ix86_lea_decompose_address (rtx, struct ix86_address *); static int legitimate_address_parts_p (const struct ix86_address *, int); static void print_operand_address_parts (FILE *, const struct ix86_address *); @@ -8796,7 +8795,7 @@ instruction. WARNING: This is a copy-paste of the original ix86_decompose_address. */ -static int +int ix86_lea_decompose_address (rtx addr, struct ix86_address *out) { rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX; diff --git a/gcc/gcc/config/i386/i386.md b/gcc/gcc/config/i386/i386.md index 93223b2..59c02d0 100644 --- a/gcc/gcc/config/i386/i386.md +++ b/gcc/gcc/config/i386/i386.md
@@ -2435,21 +2435,19 @@ if (!(REG_P (operands[1]) && REGNO (operands[1]) == SP_REG)) return "naclrestbp\t{%k1, %%r15|%%r15, %k1}"; - /* Get RSP. */ + /* Get RSP. + This also truncated RSP when spilling? it to MEM, which should + still work as fill will use naclrestsp. */ if (REG_P (operands[1]) && REGNO (operands[1]) == SP_REG) - { - gcc_assert (REG_P (operands[0])); - if (REGNO (operands[0]) != BP_REG) - return "mov{l}\t{%k1, %k0|%k0, %k1}"; - } + if (!(REG_P (operands[0]) && REGNO (operands[0]) == BP_REG)) + return "mov{l}\t{%k1, %k0|%k0, %k1}"; - /* Get RBP. */ + /* Get RBP. + This also truncated RBP when spilling? it to MEM, which should + still work as fill will use naclrestbp. */ if (REG_P (operands[1]) && REGNO (operands[1]) == BP_REG) - { - gcc_assert (REG_P (operands[0])); - if (REGNO (operands[0]) != SP_REG) - return "mov{l}\t{%k1, %k0|%k0, %k1}"; - } + if (!(REG_P (operands[0]) && REGNO (operands[0]) == SP_REG)) + return "mov{l}\t{%k1, %k0|%k0, %k1}"; } return "mov{q}\t{%1, %0|%0, %1}"; } @@ -6009,7 +6007,23 @@ [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "lea_address_operand" "T"))] "TARGET_64BIT" - "lea{q}\t{%Z1, %0|%0, %Z1}" +{ + if (TARGET_NACL) + { + struct ix86_address parts; + int ok; + + ok = ix86_lea_decompose_address (operands[1], &parts); + gcc_assert (ok); + + if (parts.base) + { + if (REGNO (parts.base) == SP_REG || REGNO (parts.base) == BP_REG) + return "lea{l}\t{%Z1, %k0|%k0, %Z1}"; + } + } + return "lea{q}\t{%Z1, %0|%0, %Z1}"; +} [(set_attr "type" "lea") (set_attr "mode" "DI")])